package com.netintech.service;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * @Author changjianbao
 * @Description 业务处理器
 * @Date 2019/8/7 8:21
 * @Param
 * @return
 **/
public class ServerHandler extends SimpleChannelInboundHandler<Person> {
    private static final Logger logger = LoggerFactory.getLogger(ServerHandler.class);
    /** 空闲次数 */
    private int idle_count = 1;
    /**
     * @Author changjianbao
     * @Description 超时处理，如果5秒没有收到客户端的心跳，就触发; 如果超过两次，则直接关闭;
     * @Date 2019/8/6 13:50
     * @Param
     * @return
     **/
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object obj) throws Exception {
        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String clientIp = ipSocket.getAddress().getHostAddress();
        if (obj instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) obj;
            if (IdleState.READER_IDLE.equals(event.state())) { // 如果读通道处于空闲状态，说明没有接收到心跳命令
                if (idle_count > 2) {
                    logger.error("超过两次无客户端【== "+clientIp+" ==】请求，关闭该channel");
                    ctx.channel().close();
                    Utils.map.remove(clientIp);
                }
                logger.error("已等待5秒还没收到客户端【== "+clientIp+" ==】发来的消息");
                idle_count++;
            }
        } else {
            super.userEventTriggered(ctx, obj);
        }
    }
    /**
     * @Author changjianbao
     * @Description 客户端连接  客户端信息
     * @Date 2019/8/6 13:49
     * @Param [ctx]
     * @return void
     **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String clientIp = ipSocket.getAddress().getHostAddress();
        Utils.map.put(clientIp,ctx);
        logger.info("当前连接的客户端数量为：【 "+Utils.map.size()+" 】");
        Utils.map.size();
        send(clientIp);
        logger.info("客户端ip地址：【== {}",clientIp+" ==】连接成功了----->");
    }
    /**
     * @Author changjianbao
     * @Description 数据业务处理
     * @Date 2019/8/6 13:49
     * @Param [ctx]
     * @return void
     **/
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Person person2) throws Exception {
        InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
        String clientIp = ipSocket.getAddress().getHostAddress();
        logger.info("----------------------------新数据包start----------------------------");
//        String s = new String(person2.getBody(),"UTF-8");
//        String sarr[] = s.trim().split(" ");
//        logger.info("接收到来自客户端【== "+clientIp+" ==】的数据为："+s);
        logger.info("接收到来自客户端【== "+clientIp+" ==】的数据数组："+ Arrays.toString(person2.getBody()));
        logger.info("接收到来自客户端【== "+clientIp+" ==】的数据数组："+ Utils.bytesToHex(person2.getBody()));
        logger.info("----------------------------新数据包end----------------------------");
//        ByteBuf r = Unpooled.copiedBuffer("数据收到了111111111111111111", Charset.forName("utf-8"));
//        ctx.writeAndFlush(r);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
    /**
     * @Author changjianbao
     * @Description 向指定通道发送数据
     * @Date 2019/8/6 15:57
     * @Param []
     * @return void
     **/
    public void send(String clientIp){
        ChannelHandlerContext ctx = (ChannelHandlerContext)Utils.map.get(clientIp);
        ByteBuf r = Unpooled.copiedBuffer("我们已经连接上了", Charset.forName("utf-8"));
        ctx.writeAndFlush(r);
    }
    /**
     * @Author changjianbao
     * @Description 向指定通道发送数据；控制机器开关
     * @Date 2019/8/6 15:57
     * @Param []
     * @return void
     **/
    public void open(String clientIp){
        ChannelHandlerContext ctx = (ChannelHandlerContext)Utils.map.get(clientIp);
        String sa = "EAA1A107080808080808080B01000006E1";
        byte[] b = Utils.hexToByteArray(sa);
        ctx.writeAndFlush(b);
    }
}
